/**
 * edatagrid - jQuery EasyUI
 * 
 * Licensed under the GPL:
 *   http://www.gnu.org/licenses/gpl.txt
 *
 * Copyright 2011 stworthy [ stworthy@gmail.com ] 
 * 
 * Dependencies:
 *   datagrid
 *   messager
 * 
 */

(function($){
	var currTarget;
	$(function(){
		$(document).unbind('.edatagrid').bind('mousedown.edatagrid', function(e){
			var p = $(e.target).closest('div.datagrid-view,div.combo-panel');
			if (p.length){
				if (p.hasClass('datagrid-view')){
					var dg = p.children('table');
					if (dg.length && currTarget != dg[0]){
						_save();
					}
				}
				return;
			}
			_save();
			
			function _save(){
				var dg = $(currTarget);
				if (dg.length){
					dg.edatagrid('saveRow');
					currTarget = undefined;
				}
			}
		});
	});
	
	function renderRow(target, fields, frozen, rowIndex, rowData) {
		var opts = $.data(target, "datagrid").options;
		var cc = [];
		//全局index
		if (frozen && opts.rownumbers) {
			var _1fc = rowIndex + 1;
			if (opts.pagination) {
				_1fc += (opts.pageNumber - 1) * opts.pageSize;
			}
			cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">"+ _1fc + "</div></td>");
		}
		for (var i = 0; i < fields.length; i++) {
			var field = fields[i];
			var col = $(target).datagrid("getColumnOption", field);
			if (col) {
				var value = rowData[field];
				var css = col.styler ? (col.styler(value, rowData, rowIndex) || "") : "";
				var _1ff = "";
				var _200 = "";
				if (typeof css == "string") {
					_200 = css;
				} else {
					if (css) {
						_1ff = css["class"] || "";
						_200 = css["style"] || "";
					}
				}
				var cls = _1ff ? "class=\"" + _1ff + "\"" : "";
				var _201 = col.hidden ? "style=\"display:none;" + _200 + "\""
						: (_200 ? "style=\"" + _200 + "\"" : "");
				cc.push("<td field=\"" + field + "\" " + cls + " " + _201 + ">");
				var _201 = "";
				if (!col.checkbox) {
					if (col.align) {
						_201 += "text-align:" + col.align + ";";
					}
					if (!opts.nowrap) {
						_201 += "white-space:normal;height:auto;";
					} else {
						if (opts.autoRowHeight) {
							_201 += "height:auto;";
						}
					}
				}
				cc.push("<div style=\"" + _201 + "\" ");
				cc.push(col.checkbox ? "class=\"datagrid-cell-check\""
						: "class=\"datagrid-cell " + col.cellClass + "\"");
				cc.push(">");
				if (col.checkbox) {
					cc.push("<input type=\"checkbox\" "
							+ (rowData.checked ? "checked=\"checked\"" : ""));
					cc.push(" name=\"" + field + "\" value=\""
							+ (value != undefined ? value : "") + "\">");
				} else {
					if (col.formatter) {
						cc.push(col.formatter(value, rowData, rowIndex, field));
					} else {
						cc.push(value);
					}
				}
				cc.push("</div>");
				cc.push("</td>");
			}
		}
		return cc.join("");
	}
	
	function buildGrid(target){
		var opts = $.data(target, 'edatagrid').options;
		$(target).datagrid($.extend({}, opts, {
			onDblClickCell:function(index,field,value){
				if (opts.editing){
					$(this).edatagrid('editRow', index);
					focusEditor(field);
				}
				if (opts.onDblClickCell){
					opts.onDblClickCell.call(target, index, field, value);
				}
			},
			onClickCell:function(index,field,value){
				if (opts.editing && opts.editIndex >= 0){
					$(this).edatagrid('editRow', index);
					focusEditor(field);
				}
				if (opts.onClickCell){
					opts.onClickCell.call(target, index, field, value);
				}
			},
			onAfterEdit : function(index, row, changes){
				opts.editIndex = -1;
				var changed=0;
				for(var t in changes) {changed++;break;}
				var url = opts.saveUrl;
				if(opts.autoSave&&url&&changed!=0){
					$.post(url, row, function(data){
						if (data.isError){
							$(target).edatagrid('cancelRow',index);
							$(target).edatagrid('selectRow',index);
							$(target).edatagrid('editRow',index);
							opts.onError.call(target, index, data);
							return;
						}
						data.isNewRecord = null;
						$(target).datagrid('updateRow', {
							index: index,
							row: data
						});
						opts.onSave.call(target, index, row);
					},'json');
				}
				if (opts.onAfterEdit){
					opts.onAfterEdit.call(index, row, changes);
				}
			},
			oncancelRowEdit: function(index, row){
				opts.editIndex = -1;
				if (row.isNewRecord) {
					$(this).datagrid('deleteRow', index);
				}
				if (opts.onCancelEdit) opts.onCancelEdit.call(target, index, row);
			},
			view: $.extend({}, opts.view, {
				onBeforeRender: function(target, rows){
					$(target).edatagrid('cancelRow');
					opts.view.onBeforeRender.call(this, target, rows);
				},
				renderRow : renderRow
			})
		}));
		
		fieldPlus();
		
		function fieldPlus(){
			var fields=$(target).datagrid("getColumnFields",'true');
			for(var i=0;i<fields.length;i++){
				var opts=$(target).datagrid("getColumnOption",fields[i]);
				if($.type(opts.flexset)=='string'&&opts.editor=='combobox'){
					opts.editor={type:'combobox',
							options:{valueField:'code',textField:'name',data:plat.FlexUtil.getValue(opts.flexset)}
						};
					opts.formatter=comboboxformater;
				}else if(opts.editor=='datebox'){
					opts.formatter=dateboxFormatter;
				}else if(opts.editor=='datetimebox'){
					opts.formatter=datetimeboxFormatter;
				}if(opts.editor=='numberbox'){
					opts.formatter=numberboxFormater;
				}
			}
		}
		
		function comboboxformater(value,row,index,field){
			var opts=$(target).datagrid("getColumnOption",field);
			return plat.FlexUtil.getName(opts.flexset,value);
		}
		
		function dateboxFormatter(value,row,index,field){
			var date=$.fn.datebox.defaults.parser(value);
			return $.fn.datebox.defaults.formatter(date);
		}
		
		function datetimeboxFormatter(value,row,index,field){
			var date=$.fn.datetimebox.defaults.parser(value);
			var h=date.getHours();
			var M=date.getMinutes();
			var s=date.getSeconds();
			function _2a(_2b){
				return (_2b<10?"0":"")+_2b;
			};
			var spliter=":"
			return $.fn.datebox.defaults.formatter(date)+" "+_2a(h)+spliter+_2a(M)+spliter+_2a(s);
		}
		
		function numberboxFormater(value,row,index,field){
			var opts=$(target).datagrid("getColumnOption",field);
			if(!opts.precision) opts.precision=0;
			return value.toFixed(opts.precision);
		}
		
		function focusEditor(field){
			var editor = $(target).datagrid('getEditor', {index:opts.editIndex,field:field});
			if (editor){
				editor.target.focus();
			} else {
				var editors = $(target).datagrid('getEditors', opts.editIndex);
				if (editors.length){
					editors[0].target.focus();
				}
			}
		}
	}
	
	$.fn.edatagrid = function(options, param){
		if (typeof options == 'string'){
			var method = $.fn.edatagrid.methods[options];
			if (method){
				return method(this, param);
			} else {
				return this.datagrid(options, param);
			}
		}
		
		options = options || {};
		return this.each(function(){
			var state = $.data(this, 'edatagrid');
			if (state){
				$.extend(state.options, options);
			} else {
				$.data(this, 'edatagrid', {
					options: $.extend({}, $.fn.edatagrid.defaults, $.fn.edatagrid.parseOptions(this), options)
				});
			}
			buildGrid(this);
		});
	};
	
	$.fn.edatagrid.parseOptions = function(target){
		return $.extend({}, $.fn.datagrid.parseOptions(target), {
		});
	};
	
	$.fn.edatagrid.methods = {
		options: function(jq){
			var opts = $.data(jq[0], 'edatagrid').options;
			return opts;
		},
		enableEditing: function(jq){
			return jq.each(function(){
				var opts = $.data(this, 'edatagrid').options;
				opts.editing = true;
			});
		},
		disableEditing: function(jq){
			return jq.each(function(){
				var opts = $.data(this, 'edatagrid').options;
				opts.editing = false;
			});
		},
		editRow: function(jq, index){
			return jq.each(function(){
				var dg = $(this);
				var opts = $.data(this, 'edatagrid').options;
				var editIndex = opts.editIndex;
				if (editIndex != index){
					if (dg.datagrid('validateRow', editIndex)){
						if (editIndex>=0){
							if (opts.onBeforeSave.call(this, editIndex) == false) {
								setTimeout(function(){
									dg.datagrid('selectRow', editIndex);
								},0);
								return;
							}
						}
						dg.datagrid('endEdit', editIndex);
						dg.datagrid('beginEdit', index);
						opts.editIndex = index;
						
						if (currTarget != this && $(currTarget).length){
							$(currTarget).edatagrid('saveRow');
							currTarget = undefined;
						}
						if (opts.autoSave){
							currTarget = this;
						}
						
						var rows = dg.datagrid('getRows');
						opts.onEdit.call(this, index, rows[index]);
					} else {
						setTimeout(function(){
							dg.datagrid('selectRow', editIndex);
						}, 0);
					}
				}
			});
		},
		addRow: function(jq, index){
			return jq.each(function(){
				var dg = $(this);
				var opts = $.data(this, 'edatagrid').options;
				if (opts.editIndex >= 0){
					if (!dg.datagrid('validateRow', opts.editIndex)){
						dg.datagrid('selectRow', opts.editIndex);
						return;
					}
					if (opts.onBeforeSave.call(this, opts.editIndex) == false){
						setTimeout(function(){
							dg.datagrid('selectRow', opts.editIndex);
						},0);
						return;
					}
					dg.datagrid('endEdit', opts.editIndex);
				}
				var rows = dg.datagrid('getRows');
				
				function _add(index, row){
					if (index == undefined){
						dg.datagrid('appendRow', row);
						opts.editIndex = rows.length - 1;
					} else {
						dg.datagrid('insertRow', {index:index,row:row});
						opts.editIndex = index;
					}
				}
				if (typeof index == 'object'){
					_add(index.index, $.extend(index.row, {isNewRecord:true}))
				} else {
					_add(index, {isNewRecord:true});
				}
				
				dg.datagrid('beginEdit', opts.editIndex);
				dg.datagrid('selectRow', opts.editIndex);
				
				opts.onAdd.call(this, opts.editIndex, rows[opts.editIndex]);
			});
		},
		saveRow: function(jq){
			return jq.each(function(){
				var dg = $(this);
				var opts = $.data(this, 'edatagrid').options;
				if (opts.editIndex >= 0){
					if (opts.onBeforeSave.call(this, opts.editIndex) == false) {
						setTimeout(function(){
							dg.datagrid('selectRow', opts.editIndex);
						},0);
						return;
					}
					$(this).datagrid('endEdit', opts.editIndex);
				}
			});
		},
		cancelRow: function(jq){
			return jq.each(function(){
				var opts = $.data(this, 'edatagrid').options;
				if (opts.editIndex >= 0){
					$(this).datagrid('cancelEdit', opts.editIndex);
					opts.editIndex=-1;
				}
			});
		},
		destroyRow: function(jq, index){
			return jq.each(function(){
				var dg = $(this);
				var opts = $.data(this, 'edatagrid').options;
				
				var rows = [];
				if (index == undefined){
					rows = dg.datagrid('getSelections');
				} else {
					var rowIndexes = $.isArray(index) ? index : [index];
					for(var i=0; i<rowIndexes.length; i++){
						var row = opts.finder.getRow(this, rowIndexes[i]);
						if (row){
							rows.push(row);
						}
					}
				}
				
				if (!rows.length){
					$.messager.show({
						title: opts.destroyMsg.norecord.title,
						msg: opts.destroyMsg.norecord.msg
					});
					return;
				}
				
				$.messager.confirm(opts.destroyMsg.confirm.title,opts.destroyMsg.confirm.msg,function(r){
					if (r){
						for(var i=0; i<rows.length; i++){
							_del(rows[i]);
						}
						dg.datagrid('clearSelections');
					}
				});
				
				function _del(row){
					var index = dg.datagrid('getRowIndex', row);
					if (index == -1){return}
					if (row.isNewRecord){
						dg.datagrid('cancelEdit', index);
					} else {
						if (opts.destroyUrl){
							$.post(opts.destroyUrl, row, function(data){
								dg.datagrid('cancelEdit', index);
								dg.datagrid('deleteRow', index);
								opts.onDestroy.call(dg[0], index, row);
								var pager = dg.datagrid('getPager');
								if (pager.length && !dg.datagrid('getRows').length){
									dg.datagrid('options').pageNumber = pager.pagination('options').pageNumber;
									dg.datagrid('reload');
								}
							}, 'json');
						} else {
							dg.datagrid('cancelEdit', index);
							dg.datagrid('deleteRow', index);
							opts.onDestroy.call(dg[0], index, row);
						}
					}
				}
			});
		}
	};
	
	$.fn.edatagrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
		singleSelect: true,
		editing: true,
		editIndex: -1,
		destroyMsg:{
			norecord:{
				title:'Warning',
				msg:'No record is selected.'
			},
			confirm:{
				title:'Confirm',
				msg:'Are you sure you want to delete?'
			}
		},
		
		autoSave: false,	// auto save the editing row when click out of datagrid
		url: null,	// return the datagrid data
		saveUrl: null,	// return the added row
		destroyUrl: null,	// return {success:true}
		
		onAdd: function(index, row){},
		onEdit: function(index, row){},
		onBeforeSave: function(index){},
		onSave: function(index, row){},
		onDestroy: function(index, row){},
		onError: function(index, row){}
	});
	
	$.parser.plugins.push('edatagrid');
})(jQuery);